﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BrokerBase.Lib.Company;
using BrokerBase.Lib.Base;
using BrokerBase.Lib.Tool;
using BrokerBase.Lib.Core;

namespace BrokerBase.Lib.Product
{
    public  abstract class Product:PKItem,IProduct
    {
        private bool isCompiled;

        //private string[,] fixRateFactors;

        public Product()
        {
            ColRateFactors = new List<IRateFactor>();
            RowRateFactors = new List<IRateFactor>();
            PaymentPeriods = new List<IPaymentPeriod>();
            InsurancePeriods = new List<IInsurancePeriod>();
            RateRows = new List<IRateRow>();
            AdjustRates = new List<IAdjustRate>();
            AuxProperties = new List<IAuxProperty>();
            Duties = new List<IDuty>();
            PaymentCycles = new List<ITimeUnit>();
            BasicAmounts = new List<IBasicAmount>();
            BasicAmounts.Add(new BasicAmount(this,"1000元", 1000, 1000, null));
            Relations = new List<IRelation>();
        }

        public virtual string SimpleName 
        {
            get
            {
                string[] ns = Name.Split('_');

                return ns[1];
            }
        }

        public virtual ICompany Company{get;set;}

        public abstract ProductType ProductType{get;}

        public virtual string Catalog { get; set; }

        public virtual ITimeUnit TimeUnit{get;set;}

        public virtual bool IsBasicAmountsFromFixRate { get; set; }

        public virtual UnitType UnitType { get; set; }

        public virtual IList<IBasicAmount> BasicAmounts { get; set; }

        public virtual bool IsPaymentPeriodsFromFixRate { get; set; }

        public virtual IList<IPaymentPeriod> PaymentPeriods{get;set;}

        public virtual bool IsInsurancePeriodsFromFixRate { get; set; }

        public virtual IList<IInsurancePeriod> InsurancePeriods{get;set;}

        public virtual bool CanOverPeriod 
        {
            get
            {
                if (PaymentPeriods.Count == 1 && PaymentPeriods[0].Value == 1 && InsurancePeriods.Count == 1 && InsurancePeriods[0].Style == InsurancePeriodStyle.EqualPayPeriod)
                    return true;
                else if (PaymentPeriods.Count == 1 && PaymentPeriods[0].Style == PaymentPeriodStyle.Lifetime)
                    return true;
                else
                    return false;
            }
        }

        public virtual bool CanSetOverPeriod 
        {
            get { return CanOverPeriod && PaymentPeriods[0].Style != PaymentPeriodStyle.Lifetime; }
        }

        public virtual IList<ITimeUnit> PaymentCycles { get; set; }

        public virtual IList<IRateFactor> ColRateFactors{get;set;}

        public virtual IList<IRateFactor> RowRateFactors { get; set; }

        public virtual RateType RateType{get;set;}

        public virtual int MaxRateCol { get; set; }

        public virtual int MaxRateRow { get; set; }

        public virtual IList<IRateRow> RateRows{get;set;}

        public virtual bool IsLadderAmount { get { return ColRateFactors.FirstOrDefault(p=>p.IsLadderConverter)!=null;} }

        public virtual IList<IAdjustRate> AdjustRates{get;set;}

        public virtual IList<IAuxProperty> AuxProperties { get; set; }

        public virtual IList<IDuty> Duties { get; set; }

        public virtual IExpandExpress ExpandExpress { get; set; }

        public virtual IProductExpander Expander
        {
            get
            {
                IProductExpander ep = null;

                if (ExpandExpress != null && ExpandExpress.IsVerify)
                {
                    ep = ExpandExpress.Expander;
                }
                else
                {
                    ep = new DefaultProductExpander();
                }

                return ep;
            }
        }

        public virtual IList<IRelation> Relations { get; set; }

        public virtual IList<string> GetColRateKeys()
        {
            IList<string> ls = new List<string>();

            for (int i = 0; i < ColRateFactors.Count; i++)
            {
                string[] s = ColRateFactors[i].Items.Split(';');

                for (int j = 0; j < s.Count(); j++)
                {
                    if (!string.IsNullOrEmpty(s[j]))
                    {
                        if (j >= ls.Count)
                            ls.Add(string.Empty);

                        ls[j] += string.IsNullOrEmpty(ls[j]) ? s[j] : "-" + s[j];
                    }
                }
            }

            return ls;
        }

        public virtual IList<string> InsurantStates 
        {
            get
            {
                string s = string.Empty;
                foreach (var v in Duties)
                {
                    s += ";"+v.InsurantStates;
                }

                IList<string> ls = s.Split(';').Where(k=>!string.IsNullOrEmpty(k)).GroupBy(p => p).Select(g => g.Key).ToList<string>();

                return ls;
            }
        }

        public virtual IList<string> HolderStates 
        {
            get
            {
                string s = string.Empty;
                foreach (var v in Duties)
                {
                    s += ";" + (string.IsNullOrEmpty(v.HolderStates)?string.Empty:v.HolderStates.Trim());
                }

                

                IList<string> ls = s.Split(';').Where(k => !string.IsNullOrEmpty(k)).GroupBy(p => p).Select(g => g.Key).ToList<string>();

                return ls;
            }
        }

        public virtual bool IsCompiled 
        { 
            get { return isCompiled; } 
            set { isCompiled = value; }
        }

        public virtual void Compile()
        {
            bool succes = false;
            string info = null;
            ProductUtil.CreateDutyAction(Duties,out succes,out info);

            if (succes)
            {
                isCompiled = true;
            }
            else
            {
                BaseLibGlobal.Log.Error(info);
            }
        }

        public virtual DateTime? CheckTime{get;set;}


        public virtual string CheckerName { get; set; }


        public virtual bool IsCheck
        {
            get { return CheckTime != null; }
        }

        public virtual int? MaxPayAge 
        {
            get
            {
                IRateFactor rateFactor = this.RowRateFactors.FirstOrDefault(p => p.Name.Contains("年龄"));

                int? age = null;

                if (rateFactor!=null && rateFactor.Axis == RateFactorAxis.Row)
                {
                    IRateRow rr= this.RateRows.Last();

                    string s = !string.IsNullOrEmpty(rr.Key2) ? rr.Key2 : rr.Key1;

                    age= Convert.ToInt32(s);
                }

                return age;

            }
        }
    }
}
